package cn.wch.ch934xlib.connet;

import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbRequest;

import androidx.annotation.NonNull;

import java.nio.ByteBuffer;
import java.util.HashMap;

public class UsbRequestArrayPool implements IUsbRequestPool{

    private static UsbRequestArrayPool usbRequestPool;

    private HashMap<UsbEndpoint,UsbRequest[]> requestHashMap;
    private HashMap<UsbEndpoint,Integer> requestIndexMap;
    private HashMap<UsbRequest,ByteBuffer> bufferHashMap;

    public static UsbRequestArrayPool getInstance() {
        if(usbRequestPool==null){
            synchronized (UsbRequestArrayPool.class){
                usbRequestPool=new UsbRequestArrayPool();
            }
        }
        return usbRequestPool;
    }
    private int requestCount=16;

    public UsbRequestArrayPool() {
        requestHashMap=new HashMap<>();
        requestIndexMap=new HashMap<>();
        bufferHashMap=new HashMap<>();
    }

    public void init(@NonNull UsbDeviceConnection usbDeviceConnection, @NonNull UsbEndpoint usbEndpoint){
        int maxPacketSize = usbEndpoint.getMaxPacketSize();
        //初始化request
        UsbRequest[] requests=new UsbRequest[requestCount];
        for (int i = 0; i < requests.length; i++) {
            ByteBuffer byteBuffer=ByteBuffer.allocate(maxPacketSize);
            UsbRequest request=new UsbRequest();
            request.initialize(usbDeviceConnection,usbEndpoint);
            bufferHashMap.put(request, byteBuffer);
            requests[i]=request;
        }
        requestHashMap.put(usbEndpoint,requests);
        requestIndexMap.put(usbEndpoint,0);
        queue(usbEndpoint);
    }

    @Override
    public void queue(@NonNull UsbEndpoint usbEndpoint) {
        UsbRequest usbRequest = getUsbRequest(usbEndpoint);
        if(usbRequest==null){
            return;
        }
        ByteBuffer byteBuffer = bufferHashMap.get(usbRequest);
        if(byteBuffer==null){
            return;
        }
        byteBuffer.clear();
        usbRequest.queue(byteBuffer,byteBuffer.capacity());
    }


    public UsbRequest getUsbRequest(@NonNull UsbEndpoint usbEndpoint){

        int currentIndex = getCurrentIndex(usbEndpoint);
        if(currentIndex<0){
            return null;
        }
        UsbRequest[] requests = requestHashMap.get(usbEndpoint);
        if(requests==null || requests.length<=currentIndex){
            return null;
        }
        return requests[currentIndex];
    }


    public ByteBuffer getBuffer(@NonNull UsbEndpoint usbEndpoint){
        UsbRequest usbRequest = getUsbRequest(usbEndpoint);
        if(usbRequest==null){
            return null;
        }
        return bufferHashMap.get(usbRequest);
    }

    private int getCurrentIndex(@NonNull UsbEndpoint usbEndpoint){
        Integer integer = requestIndexMap.get(usbEndpoint);
        if(integer==null){
            return -1;
        }
        return integer;
    }
}
